package java8;

import java.util.Arrays;
import java.util.List;

/**
 * @projectName: java-sample
 * @description:
 * @author: Adam
 * @create: 2019-11-06 15:43
 **/

public class LamdbaDemo {

    /*函数式编程的目的是使用函数来抽象作用在数据之上的控制流和操作，从而在系统中消除副作用并减少对状态的改变。*/

    /*函数式接口：概述:接口中只有一个抽象方法
    函数式接口，即适用于函数式编程场景的接口。而Java中的函数式编程体现就是Lambda，所以函数式接口就是可
    以适用于Lambda使用的接口。只有确保接口中有且仅有一个抽象方法，Java中的Lambda才能顺利地进行推导。*/
   /* 匿名内部类的接口类型的参数可以有多个抽象方法，lamdba表达式中必须是函数式接口*/

    /*我开始使用Java 8时，首先做的就是使用lambda表达式替换匿名类，而实现Runnable接口是匿名类的最好示例。
    看一下Java 8之前的runnable实现方法，需要4行代码，而使用lambda表达式只需要一行代码。
    我们在这里做了什么呢？那就是用() -> {}代码块替代了整个匿名类。*/
    /*可以使用lambda写出如下代码：
        (params) -> expression
        (params) -> statement
        (params) -> { statements }*/

    public static void main(String[] args){

    }

    //lamdba 用于创建线程
    public void threadDemo(){
        //Runnable 接口中只有一个抽象方法 run
        //JAVA8之前
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Before Java8, too much code for too little to do");
            }
        }).start();

        //java8之后
        new Thread( () -> System.out.println("In Java8, Lambda expression rocks !!") ).start();
    }


    //lamdba与集合
    public void collectionDemo(){
        // Java 8之前：
        List<String> features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API");
        for (String feature : features) {
            System.out.println(feature);
        }

        // Java 8之后：
        List<String> feature = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API");
        feature.forEach(n -> System.out.println(n));
        // 使用Java 8的 方法引用 更方便，方法引用由::双冒号操作符标示，
        // 看起来像C++的作用域解析运算符
        features.forEach(System.out::println);

    }

    public void methodUse(){
        /*方法引用是用来直接访问类或者实例的已经存在的方法或者构造方法。方法引用提供了一种引用而不执行方法的方式，
        它需要由兼容的函数式接口构成的目标类型上下文。计算时，方法引用会创建函数式接口的一个实例。
        当Lambda表达式中只是执行一个方法调用时，不用Lambda表达式，直接通过方法引用的形式可读性更高一些。【方法引用是一种更简洁易懂的Lambda表达式】。
        注意方法引用是一个Lambda表达式，其中方法引用的操作符是双冒号"::"。
        简单地说，就是一个Lambda表达式。在Java 8中，我们会使用Lambda表达式创建匿名方法，
        【但是有时候，我们的Lambda表达式可能仅仅调用一个已存在的方法，而不做任何其它事，对于这种情况，通过一个方法名字来引用这个已存在的方法会更加清晰】，
        Java 8的方法引用允许我们这样做。方法引用是一个更加紧凑，易读的Lambda表达式，注意方法引用是一个Lambda表达式，其中方法引用的操作符是双冒号"::"*/
    }

}
